<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow-IPC: ipc::transport::Protocol_negotiator Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow-IPC<span id="projectnumber">&#160;1.0.2</span>
   </div>
   <div id="projectbrief">Flow-IPC project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceipc.html">ipc</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1transport.html">transport</a></li><li class="navelem"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-types">Public Types</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-attribs">Static Public Attributes</a> &#124;
<a href="classipc_1_1transport_1_1Protocol__negotiator-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">ipc::transport::Protocol_negotiator Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state machine, helps negotiate the protocol version to speak over that pathway, given each side being capable of speaking a range of protocol versions and reporting the highest such version to the other side.  
 <a href="classipc_1_1transport_1_1Protocol__negotiator.html#details">More...</a></p>

<p><code>#include &lt;protocol_negotiator.hpp&gt;</code></p>

<p>Inherits flow::log::Log_context.</p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-types" name="pub-types"></a>
Public Types</h2></td></tr>
<tr class="memitem:a35fb3885d39f11d0c1f7860e64194592"><td class="memItemLeft" align="right" valign="top"><a id="a35fb3885d39f11d0c1f7860e64194592" name="a35fb3885d39f11d0c1f7860e64194592"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>proto_ver_t</b> = int16_t</td></tr>
<tr class="memdesc:a35fb3885d39f11d0c1f7860e64194592"><td class="mdescLeft">&#160;</td><td class="mdescRight">Type sufficient to store a protocol version; positive values identify newer versions of a protocol; while non-positive values S_VER_UNKNOWN and S_VER_UNSUPPORTED are special values. <br /></td></tr>
<tr class="separator:a35fb3885d39f11d0c1f7860e64194592"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a427c54f57df581027a330eb0f7146904"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a427c54f57df581027a330eb0f7146904">Protocol_negotiator</a> (flow::log::Logger *logger_ptr, <a class="el" href="namespaceipc_1_1util.html#ae6ac47812a90d1287c61e0b7de7bc4f5">util::String_view</a> nickname, <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a> local_max_proto_ver, <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a> local_min_proto_ver)</td></tr>
<tr class="memdesc:a427c54f57df581027a330eb0f7146904"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs a comm pathway's negotiator object in initial state wherein: (1) <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> returns <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292" title="A proto_ver_t value, namely a negative one, which is a reserved value indicating &quot;unknown version&quot;; i...">S_VER_UNKNOWN</a> (not yet negotiated with opposing <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a>); and (2) we've not yet sent <code>local_max_proto_ver</code> to opposing side via first being queried using <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af" title="To be called at most once, this returns local_max_proto_ver from ctor the first time and S_VER_UNKNOW...">local_max_proto_ver_for_sending()</a>.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#a427c54f57df581027a330eb0f7146904">More...</a><br /></td></tr>
<tr class="separator:a427c54f57df581027a330eb0f7146904"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae4a1edcf2f1a0ae3e86b2ab93b71da0f"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#ae4a1edcf2f1a0ae3e86b2ab93b71da0f">Protocol_negotiator</a> (const <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;src)</td></tr>
<tr class="memdesc:ae4a1edcf2f1a0ae3e86b2ab93b71da0f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy-constructs <code>*this</code> to be equal to <code>src</code> object.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#ae4a1edcf2f1a0ae3e86b2ab93b71da0f">More...</a><br /></td></tr>
<tr class="separator:ae4a1edcf2f1a0ae3e86b2ab93b71da0f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aeb1b9e12cdfaa702c8a81b7ff81f1801"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aeb1b9e12cdfaa702c8a81b7ff81f1801">Protocol_negotiator</a> (<a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:aeb1b9e12cdfaa702c8a81b7ff81f1801"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move-constructs <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if defaulted-cted.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#aeb1b9e12cdfaa702c8a81b7ff81f1801">More...</a><br /></td></tr>
<tr class="separator:aeb1b9e12cdfaa702c8a81b7ff81f1801"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae24b3bd8550a2f9ab0d728cb1832d4f5"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#ae24b3bd8550a2f9ab0d728cb1832d4f5">operator=</a> (const <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;src)</td></tr>
<tr class="memdesc:ae24b3bd8550a2f9ab0d728cb1832d4f5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy-assigns <code>*this</code> to be equal to <code>src</code>.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#ae24b3bd8550a2f9ab0d728cb1832d4f5">More...</a><br /></td></tr>
<tr class="separator:ae24b3bd8550a2f9ab0d728cb1832d4f5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d141a0758b4d0fb51f43cefb76234a6"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a3d141a0758b4d0fb51f43cefb76234a6">operator=</a> (<a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a3d141a0758b4d0fb51f43cefb76234a6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move-assigns <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if just constructed; or no-op if <code>&amp;src == this</code>.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#a3d141a0758b4d0fb51f43cefb76234a6">More...</a><br /></td></tr>
<tr class="separator:a3d141a0758b4d0fb51f43cefb76234a6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9596a28f6379b209ec1e7efcc58b8adc"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc">negotiated_proto_ver</a> () const</td></tr>
<tr class="memdesc:a9596a28f6379b209ec1e7efcc58b8adc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>S_VER_UNKNOWN</code> before <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a>; then either the positive version of the protocol we shall speak subsequently, or <code>S_VER_UNSUPPORTED</code> if the two sides are incompatible.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc">More...</a><br /></td></tr>
<tr class="separator:a9596a28f6379b209ec1e7efcc58b8adc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6e55a4ee1033bf98123cedd10e5726cb"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb">compute_negotiated_proto_ver</a> (<a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a> opposing_max_proto_ver, <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *err_code=0)</td></tr>
<tr class="memdesc:a6e55a4ee1033bf98123cedd10e5726cb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Based on the presumably-just-received-from-opposing-side value of their <code>local_max_proto_ver</code>, passed-in as the arg, calculates the protocol version we shall speak over the comm pathway, so it will be returned by <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> subsequently.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb">More...</a><br /></td></tr>
<tr class="separator:a6e55a4ee1033bf98123cedd10e5726cb"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a54480f0849ddb5635302b42ed87c43af"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af">local_max_proto_ver_for_sending</a> ()</td></tr>
<tr class="memdesc:a54480f0849ddb5635302b42ed87c43af"><td class="mdescLeft">&#160;</td><td class="mdescRight">To be called at most once, this returns <code>local_max_proto_ver</code> from ctor the first time and <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292" title="A proto_ver_t value, namely a negative one, which is a reserved value indicating &quot;unknown version&quot;; i...">S_VER_UNKNOWN</a> subsequently.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af">More...</a><br /></td></tr>
<tr class="separator:a54480f0849ddb5635302b42ed87c43af"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2b3448c9655fd1a83b8229957da1c4e2"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a2b3448c9655fd1a83b8229957da1c4e2">reset</a> ()</td></tr>
<tr class="memdesc:a2b3448c9655fd1a83b8229957da1c4e2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Resets the negotiation state, meaning back to the state as-if just after ctor invoked.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#a2b3448c9655fd1a83b8229957da1c4e2">More...</a><br /></td></tr>
<tr class="separator:a2b3448c9655fd1a83b8229957da1c4e2"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-attribs" name="pub-static-attribs"></a>
Static Public Attributes</h2></td></tr>
<tr class="memitem:a126eb85013fbeb11bcee34efbf0c79da"><td class="memItemLeft" align="right" valign="top">static constexpr <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a126eb85013fbeb11bcee34efbf0c79da">S_VER_UNSUPPORTED</a> = 0</td></tr>
<tr class="memdesc:a126eb85013fbeb11bcee34efbf0c79da"><td class="mdescLeft">&#160;</td><td class="mdescRight">A <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592" title="Type sufficient to store a protocol version; positive values identify newer versions of a protocol; w...">proto_ver_t</a> value, namely zero, which is a reserved value indicating "unsupported version"; it is not a valid version number identifying a protocol that can actually be spoken by relevant software.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#a126eb85013fbeb11bcee34efbf0c79da">More...</a><br /></td></tr>
<tr class="separator:a126eb85013fbeb11bcee34efbf0c79da"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa7e47f4f6a700aeaa9600a5426a17292"><td class="memItemLeft" align="right" valign="top">static constexpr <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292">S_VER_UNKNOWN</a> = -1</td></tr>
<tr class="memdesc:aa7e47f4f6a700aeaa9600a5426a17292"><td class="mdescLeft">&#160;</td><td class="mdescRight">A <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592" title="Type sufficient to store a protocol version; positive values identify newer versions of a protocol; w...">proto_ver_t</a> value, namely a negative one, which is a reserved value indicating "unknown version"; it is not a valid version number identifying a protocol that can actually be spoken by relevant software.  <a href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292">More...</a><br /></td></tr>
<tr class="separator:aa7e47f4f6a700aeaa9600a5426a17292"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state machine, helps negotiate the protocol version to speak over that pathway, given each side being capable of speaking a range of protocol versions and reporting the highest such version to the other side. </p>
<p >By <em>comm pathway</em> we mean a bidirectional communication channel of some sort with two mutually-opposing endpoints (it need not be full-duplex).</p>
<p >It is copyable and movable, so that the containing object can be copyable and movable too. A moved-from <code>*this</code> becomes as-if it was just constructed.</p>
<p >The algorithm followed is quite straightforward and is exposed completely in the contract of this simple API: The impetus behind this class is not for it to be able to perform some complex <code>private</code> operations but rather to provide a reusable component that both internal and (optionally) user code can reliably count on to apply the same consistent rules. So while it does some minimal work, its main value is in presenting a common algorithm that (1) achieves protocol negotiation and (2) doesn't shoot ourselves in the foot in the face of future protocol changes.</p>
<h3>The algorithm</h3>
<p >A <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> <code>*this</code> assumes it is used by a single open comm pathway's local endpoint, and that a logically-equivalent <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> (or equivalent sofwatre) is used in symmetrical fashion by the opposide side's endpoint. (For example, a <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a> in PEER state uses a <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> internally, and it therefore assumes the opposing <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a> does the same.)</p>
<p >Further we assume that there is a range of protocols for the comm pathway, such that at least version 1 (the initial version) exists, and versions 2, 3, ... may be developed (or have already been developed). There is understood to be no ambiguity as to what a version X of the protocol means: so, if certain software knows about version X at all, then what it understands protocol version X to be is exactly equal to what any other software (that also knows of version X) understands about protocol version X.</p><ul>
<li>We (the local endpoint) can speak a range of versions of the protocol: [L, H] with H &gt;= L &gt;= 1. Obviously we know L and H: i.e., the code instantiating <code>*this</code> knows L and H (in fact it gives them to our ctor).<ul>
<li>Note: Informally, one can think of H being the <em>preferred</em> version for us: We want to speak it if possible. However, if necessary, we can invoke alternative code paths to speak a lower version for compatibility.</li>
</ul>
</li>
<li>They (the opposing endpoint) can similarly speak a range [Lp, Hp], with Hp &gt; Lp &gt;= 1. However we do not, at first at least, know Lp nor Hp.</li>
<li>Each side shall speak the <em>highest</em> possible version of the protocol such that:<ul>
<li>It is in range [L, H].</li>
<li>It is in range [Lp, Hp].</li>
</ul>
</li>
<li>Therefore there are two possibilities:<ul>
<li>If there is <em>no</em> such version, then the comm pathway cannot proceed: they have no protocol version in common they can both speak. The pathway should close ASAP upon either side realizing this.</li>
<li>If there is such a version, then the comm pathway can proceed. All we need is for <em>each side</em> to determine what that version V is. Naturally each side must come to the same answer.</li>
</ul>
</li>
</ul>
<p >While there are various ways to achieve this, including a back-and-forth negotiation, we opt for something quite simple and symmetrical. (Recall that the opposide side is assumed to have a <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> (equivalent) following the same logic, and neither side shall be chosen (in our context) to be different from the other. E.g., there's no client and server dichotomy &ndash; even if in the subsequently negotiated protocol there is; that's none of our business.) The procedure:</p><ul>
<li>We send H to them, ASAP.<ul>
<li>Similarly they send Hp to us.</li>
</ul>
</li>
<li>Having received their Hp, we choose V = min(H, Hp).<ul>
<li>Similarly having received our H, they choose V = min(H, Hp). Important: This value V <em>is</em> the same on each side. However the next computation will potentially differ between the 2 sides.</li>
</ul>
</li>
<li>On our side: If V &lt; L (which is possible only if V = Hp, meaning Hp &gt; H, meaning we are more advanced than they are), we are insufficiently backwards-compatible. Therefore V = UNSUPPORTED. We should close the comm pathway ASAP.<ul>
<li>Similarly, on their side, if V &lt; Lp &ndash; they are more advanced than we are, and they don't speak enough older versions to accomodate us &ndash; then they will detect that V = UNSUPPORTED and should close the comm pathway ASAP.</li>
</ul>
</li>
<li>On our side: Otherwise (V &gt;= L), speak V from this point on.<ul>
<li>Similarly, on ther side, if V &gt;= Lp, they shall speak V from this point on.</li>
</ul>
</li>
</ul>
<p >The role of <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> is simple:</p><ul>
<li>It memorizes the local L and H as passed to its ctor, and it starts with V = UNKNOWN. <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> always simply returns V which is the chief output of a <code>*this</code>.</li>
<li>Upon receiving Hp, user gives it to <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a>; this computes V based on the above algorithm; namely: <code>(H &lt;= Hp) ? H : ((Hp &gt;= L) ? Hp : UNSUPPORTED)</code>. So <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> shall return that value (one of H, Hp, <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a126eb85013fbeb11bcee34efbf0c79da" title="A proto_ver_t value, namely zero, which is a reserved value indicating &quot;unsupported version&quot;; it is n...">S_VER_UNSUPPORTED</a>) from then on.<ul>
<li><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a> shall not be called again. One can check <code><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> == S_VER_UNKNOWN</code>, if one would rather not independently keep track of whether <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a> has been called yet or not.</li>
</ul>
</li>
<li><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af" title="To be called at most once, this returns local_max_proto_ver from ctor the first time and S_VER_UNKNOW...">local_max_proto_ver_for_sending()</a> shall return H once; after that UNSUPPORTED. This is to encourage/help the sending-out of our H exactly once, no more.</li>
</ul>
<p >Couple notes:</p><ul>
<li>If H = Hp, then everyone will agree on everything and just speak H. This is perhaps most typical. Usually then L = Lp also, but it's conceivable they're not equal (e.g. one side has a backwards-compatibility patch but not the other). It doesn't matter really.</li>
<li>Otherwise, though, there are 2 possibilities:<ul>
<li>Both sides agree on the same V, with no V = UNSUPPORTED. This occurs, if in fact there is overlap between [L, H] and [Lp, Hp], just Hp &gt; H or vice versa: One gets to speak its "preferred" protocol, while the other has to speak an earlier version.</li>
<li>One side detects V = UNSUPPORTED (the other does not). This occurs, if one side is so much newer than the other, it doesn't even have backwards-compatibility support for the other side. (And/or perhaps the protocol does not attempt to ever be backwards-compatible; so H = L and Hp = Lp always.)<ul>
<li>In this case one side will try to proceed; but it won't get far, as the other (more advanced) side will close the comm pathway instead of either sending or receiving anything beyond its H or Hp.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p >We could have avoided the latter asymmetric situation by sending over both L and H (and they both Lp and Hp); then both sides would do exactly the same computation. However it seems an unnecessary complication and payload.</p>
<h3>Key tip: Coding for version-1 versus one version versus multiple versions</h3>
<p >Using a <code>*this</code> is in and ofi itself extremely simple; just look at the API and/or read the above. What is somewhat more subtle is how to organize your comm pathway's behavior around the start, when the negotiation occurs. That part is also straightforward for the most part:</p><ul>
<li>Before you send out your first stuff, or possibly together with it, send an encoding of <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af" title="To be called at most once, this returns local_max_proto_ver from ctor the first time and S_VER_UNKNOW...">local_max_proto_ver_for_sending()</a>.</li>
<li>When reading your first stuff, read the similar encoding from the opposing side. Now <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a> will determine <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a>; call it V. From this point on:<ul>
<li>Anything you receive should be interpreted per protocol version V.<ul>
<li>This is straightforward: since the stuff that makes it possible to determine V comes first, anytime you need to know how to interpret anything else, you'll know V already.</li>
</ul>
</li>
<li>Anything you send should be according to protocol version V.</li>
</ul>
</li>
</ul>
<p >That last part is the only subtle part. The potential challenge is that if you want to send something, you may not have gotten the protocol-negotiation in-message yet; in which case you do <em>not</em> know V. If it is necessary to know it at that point, then there's no choice but to enter a would-block state of sorts, during which time any out-messages would need to be internally queued or otherwise deferred, until you do know V (have received the first in-message and called <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a>). <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> offers no help as such.</p>
<p >However there are several common situations where this concern is entirely mitigated away. If it applies to you, then you will have no problem.</p><ul>
<li>If <code>local_min_proto_ver == local_max_proto_ver</code> (to ctor, a/k/a L = H in the above algorithm sketch), meaning locally you support only one protocol version, then there is no ambiguity in any case. You know which protocol you'll speak. The only ways there'd be a problem are: (1) <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a> determines incompatibility &ndash; by which point the supposed problem is moot; and (2) the other side does the same &ndash; in which case it will close the comm pathway (not our problem, by design).<ul>
<li>In particular, if L = H = 1 &ndash; in the first release of the protocol &ndash; this is of course the case.</li>
<li>If you do not maintain backwards compatibility (e.g., L = H = 2, then next time L = H = 3, then... etc.), then this is also the case.</li>
</ul>
</li>
<li>If L does not equal H, in many (most?) cases the actual negotiated version V does not affect many (most) messages sent. E.g., if you have a "ping" message, perhaps it will never change in any version of the protocol.<ul>
<li>So the problem only occurs when there's actual ambiguity about what to send. Your code may still need to be somewhat more complex than the L=H case, but perf/responsiveness at least is less likely to be affected.</li>
</ul>
</li>
<li>If your protocol has a built-in handshake/log-in/etc. phase (where one set side is expected to send a SYN-like thing, and the other side is supposed to reply with an ACK of some kind in response), then you can specifically:<ul>
<li>Not add any version-dependent payload to the SYN-like (opening) message; or at least defer any such version-dependent interpretation thereof, until V is known shortly.</li>
<li>But, do include the version in the SYN-like (opening) message and to its ACK-like response, specifically. By the time the hand-shake completes, both sides know V and can proceed.</li>
</ul>
</li>
</ul>
<dl class="section note"><dt>Note</dt><dd>In general, for the case of initial-protocol-release &ndash; version 1 &ndash; the usefulness of <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> minimal, but it does exist. It is minimal, because <em>assuming</em> both sides promise to follow this algorithm, then <em>all</em> the code actually <em>needs</em> to do is: (1) send <code>H = 1</code> in some fashion that will never change in the future; (2) receive Hp in some fashion that will never change in the future either; and (3) explode, if Hp is not present or is not 1. This is very much doable without <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a>. However it is almost equally easy with <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a>, too; and it <em>is a good practice</em> to leverage it, so that if there is a version 2 later, the conventions in force will be unambiguous. Only then it <em>might</em> be necessary to worry about the subtle situation above, where we want to send something out whose expression depends on V, but we haven't received the protocol-negotiating in-message yet and hence don't know V yet.</dd></dl>
<h3>Safety, trust assumption</h3>
<p >We emphasize that this is not authentication. There is the implicit trust that the opposing side will be using a very specific <em>protocol for determining the rest of the protocol</em> and trust us to do the same. Furthermore there's implicit trust that the protocol versions being referred-to mean the same thing on both sides.</p>
<p >To establish this trust is well beyond the mission of <code>*this</code> class; and explaining how to do so is well beyond this doc header.</p>
<h3>Thread safety</h3>
<p >For the same <code>*this</code>, the standard default assumptions apply (mutating access disallowed concurrently with any other access) with the following potentially important exception: <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af" title="To be called at most once, this returns local_max_proto_ver from ctor the first time and S_VER_UNKNOW...">local_max_proto_ver_for_sending()</a> can be executed concurrently with any other API except itself. In other words, the outgoing-direction (<a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af" title="To be called at most once, this returns local_max_proto_ver from ctor the first time and S_VER_UNKNOW...">local_max_proto_ver_for_sending()</a>) and incoming-direction work (<a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a>, <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a>) can be safely performed independently/concurrently w/r/t each other. </p>
</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a427c54f57df581027a330eb0f7146904" name="a427c54f57df581027a330eb0f7146904"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a427c54f57df581027a330eb0f7146904">&#9670;&nbsp;</a></span>Protocol_negotiator() <span class="overload">[1/3]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">ipc::transport::Protocol_negotiator::Protocol_negotiator </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1util.html#ae6ac47812a90d1287c61e0b7de7bc4f5">util::String_view</a>&#160;</td>
          <td class="paramname"><em>nickname</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a>&#160;</td>
          <td class="paramname"><em>local_max_proto_ver</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a>&#160;</td>
          <td class="paramname"><em>local_min_proto_ver</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructs a comm pathway's negotiator object in initial state wherein: (1) <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> returns <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292" title="A proto_ver_t value, namely a negative one, which is a reserved value indicating &quot;unknown version&quot;; i...">S_VER_UNKNOWN</a> (not yet negotiated with opposing <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a>); and (2) we've not yet sent <code>local_max_proto_ver</code> to opposing side via first being queried using <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af" title="To be called at most once, this returns local_max_proto_ver from ctor the first time and S_VER_UNKNOW...">local_max_proto_ver_for_sending()</a>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for logging subsequently. </td></tr>
    <tr><td class="paramname">nickname</td><td>String to use subsequently in logging to identify <code>*this</code>. </td></tr>
    <tr><td class="paramname">local_max_proto_ver</td><td>The highest version of the protocol the comm pathway can speak; a/k/a the preferred version. Positive or undefined behavior (assertion may trip). </td></tr>
    <tr><td class="paramname">local_min_proto_ver</td><td>The lowest version of the protocol the comm pathway can speak; so either <code>local_max_proto_ver</code> (if our side has no backwards compatibility) or the oldest version with which we are backwards-compatible. Positive and at most <code>local_max_proto_ver</code> or undefined behavior (assertion may trip). </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="ae4a1edcf2f1a0ae3e86b2ab93b71da0f" name="ae4a1edcf2f1a0ae3e86b2ab93b71da0f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae4a1edcf2f1a0ae3e86b2ab93b71da0f">&#9670;&nbsp;</a></span>Protocol_negotiator() <span class="overload">[2/3]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">ipc::transport::Protocol_negotiator::Protocol_negotiator </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&#160;</td>
          <td class="paramname"><em>src</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">default</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Copy-constructs <code>*this</code> to be equal to <code>src</code> object. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>Source object. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="aeb1b9e12cdfaa702c8a81b7ff81f1801" name="aeb1b9e12cdfaa702c8a81b7ff81f1801"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aeb1b9e12cdfaa702c8a81b7ff81f1801">&#9670;&nbsp;</a></span>Protocol_negotiator() <span class="overload">[3/3]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">ipc::transport::Protocol_negotiator::Protocol_negotiator </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>src</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Move-constructs <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if defaulted-cted. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>Moved-from object that becomes as-if default-cted. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a6e55a4ee1033bf98123cedd10e5726cb" name="a6e55a4ee1033bf98123cedd10e5726cb"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6e55a4ee1033bf98123cedd10e5726cb">&#9670;&nbsp;</a></span>compute_negotiated_proto_ver()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">bool ipc::transport::Protocol_negotiator::compute_negotiated_proto_ver </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a>&#160;</td>
          <td class="paramname"><em>opposing_max_proto_ver</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Based on the presumably-just-received-from-opposing-side value of their <code>local_max_proto_ver</code>, passed-in as the arg, calculates the protocol version we shall speak over the comm pathway, so it will be returned by <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> subsequently. </p>
<p >Returns <code>true</code>; unless it has already been called &ndash; in which case it is a no-op (outside of logging); returns <code>false</code> (unless exception thrown; see next paragraph).</p>
<p >If it is not a no-op, and the result is that the two sides lack a protocol version they can both speak, a suggested truthy <code>Error_code</code> is emitted using standard Flow error-emission convention.</p>
<p >Tip: It's a reasonable tactic to potentially call this for every in-message, if you only do so after ensuring <code><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> == S_VER_UNKNOWN</code>. That will effectively ensure the negotiation occurs ASAP and at most once.</p>
<p >More formally:</p><ul>
<li>If <code><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> != S_VER_UNKNOWN</code>: does nothing except possibly logging; returns <code>false</code>. Informal tip: If you don't know whether that's the case, check for it via <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> and neither try to parse <code>opposing_max_proto_ver</code> from your in-message, nor call the present method.</li>
<li>If <code><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> == S_VER_UNKNOWN</code> (the case right after construction): Upon return <code><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> != S_VER_UNKNOWN</code> and:<ul>
<li>If <code>err_code != nullptr</code>: <code>*error_code</code> is set to truthy suggested error to emit if applicable. Returns <code>true</code>.</li>
<li>If <code>err_code == nullptr</code>: a truthy suggested error is emitted via exception.</li>
</ul>
</li>
</ul>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">opposing_max_proto_ver</td><td>Value that the opposing <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html" title="A simple state machine that, assuming the opposide side of a comm pathway uses an equivalent state ma...">Protocol_negotiator</a> (or equivalent) sent to us over pathway: their <code>local_max_proto_ver</code>. Any value is allowed (we will check that it's positive and report negotiation failure if not). Informal advice: if you were unable to parse it from your in-message, you should pass S_VER_UNKNOWN. </td></tr>
    <tr><td class="paramname">err_code</td><td>See <code>flow::Error_code</code> docs for error reporting semantics. <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> generated: <a class="el" href="namespaceipc_1_1transport_1_1error.html#adfef15ef4e76cc55d652fbd9c2797297a594bf33052a89403c734f24428007c80" title="In protocol negotiation, opposing side reported its newest protocol version is even older than the mo...">error::Code::S_PROTOCOL_NEGOTIATION_OPPOSING_VER_TOO_OLD</a> (incompatible protocol version &ndash; we're more advanced and lack backwards-compatibility for their preferred version), <a class="el" href="namespaceipc_1_1transport_1_1error.html#adfef15ef4e76cc55d652fbd9c2797297a41cb789a6a5da26e1f72139206cb9adf" title="In protocol negotiation, opposing side sent invalid version value (not positive, not a number,...">error::Code::S_PROTOCOL_NEGOTIATION_OPPOSING_VER_INVALID</a> (<code>opposing_max_proto_ver</code> is invalid: not positive). </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>false</code> if pre-condition was <code><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> != S_VER_UNKNOWN</code>, so we no-oped; <code>true</code> otherwise (unless exception thrown, only if <code>err_code == nullptr</code>. </dd></dl>

</div>
</div>
<a id="a54480f0849ddb5635302b42ed87c43af" name="a54480f0849ddb5635302b42ed87c43af"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a54480f0849ddb5635302b42ed87c43af">&#9670;&nbsp;</a></span>local_max_proto_ver_for_sending()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">Protocol_negotiator::proto_ver_t</a> ipc::transport::Protocol_negotiator::local_max_proto_ver_for_sending </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>To be called at most once, this returns <code>local_max_proto_ver</code> from ctor the first time and <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292" title="A proto_ver_t value, namely a negative one, which is a reserved value indicating &quot;unknown version&quot;; i...">S_VER_UNKNOWN</a> subsequently. </p>
<p >Tip: It's a reasonable tactic to call this when about to send any out-message; if it returns <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292" title="A proto_ver_t value, namely a negative one, which is a reserved value indicating &quot;unknown version&quot;; i...">S_VER_UNKNOWN</a>, then you've already sent it and don't need to do so now; otherwise encode this value before/with the out-message and send it.</p>
<dl class="section return"><dt>Returns</dt><dd>See above. Either a positive version number or <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292" title="A proto_ver_t value, namely a negative one, which is a reserved value indicating &quot;unknown version&quot;; i...">S_VER_UNKNOWN</a>. </dd></dl>

</div>
</div>
<a id="a9596a28f6379b209ec1e7efcc58b8adc" name="a9596a28f6379b209ec1e7efcc58b8adc"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9596a28f6379b209ec1e7efcc58b8adc">&#9670;&nbsp;</a></span>negotiated_proto_ver()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">Protocol_negotiator::proto_ver_t</a> ipc::transport::Protocol_negotiator::negotiated_proto_ver </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>S_VER_UNKNOWN</code> before <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a6e55a4ee1033bf98123cedd10e5726cb" title="Based on the presumably-just-received-from-opposing-side value of their local_max_proto_ver,...">compute_negotiated_proto_ver()</a>; then either the positive version of the protocol we shall speak subsequently, or <code>S_VER_UNSUPPORTED</code> if the two sides are incompatible. </p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="ae24b3bd8550a2f9ab0d728cb1832d4f5" name="ae24b3bd8550a2f9ab0d728cb1832d4f5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae24b3bd8550a2f9ab0d728cb1832d4f5">&#9670;&nbsp;</a></span>operator=() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp; ipc::transport::Protocol_negotiator::operator= </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&#160;</td>
          <td class="paramname"><em>src</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">default</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Copy-assigns <code>*this</code> to be equal to <code>src</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>Source object. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>*this</code>. </dd></dl>

</div>
</div>
<a id="a3d141a0758b4d0fb51f43cefb76234a6" name="a3d141a0758b4d0fb51f43cefb76234a6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3d141a0758b4d0fb51f43cefb76234a6">&#9670;&nbsp;</a></span>operator=() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp; ipc::transport::Protocol_negotiator::operator= </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html">Protocol_negotiator</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>src</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Move-assigns <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if just constructed; or no-op if <code>&amp;src == this</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>Moved-from object that becomes as-if just-cted, unless it is <code>*this</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>*this</code>. </dd></dl>

</div>
</div>
<a id="a2b3448c9655fd1a83b8229957da1c4e2" name="a2b3448c9655fd1a83b8229957da1c4e2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a2b3448c9655fd1a83b8229957da1c4e2">&#9670;&nbsp;</a></span>reset()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void ipc::transport::Protocol_negotiator::reset </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Resets the negotiation state, meaning back to the state as-if just after ctor invoked. </p>
<p >Hence: <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a9596a28f6379b209ec1e7efcc58b8adc" title="Returns S_VER_UNKNOWN before compute_negotiated_proto_ver(); then either the positive version of the ...">negotiated_proto_ver()</a> yields <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#aa7e47f4f6a700aeaa9600a5426a17292" title="A proto_ver_t value, namely a negative one, which is a reserved value indicating &quot;unknown version&quot;; i...">S_VER_UNKNOWN</a>, while <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a54480f0849ddb5635302b42ed87c43af" title="To be called at most once, this returns local_max_proto_ver from ctor the first time and S_VER_UNKNOW...">local_max_proto_ver_for_sending()</a> would yield not-<code>S_VER_UNKNOWN</code>. </p>

</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="aa7e47f4f6a700aeaa9600a5426a17292" name="aa7e47f4f6a700aeaa9600a5426a17292"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa7e47f4f6a700aeaa9600a5426a17292">&#9670;&nbsp;</a></span>S_VER_UNKNOWN</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">constexpr <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a> ipc::transport::Protocol_negotiator::S_VER_UNKNOWN = -1</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span><span class="mlabel">constexpr</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>A <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592" title="Type sufficient to store a protocol version; positive values identify newer versions of a protocol; w...">proto_ver_t</a> value, namely a negative one, which is a reserved value indicating "unknown version"; it is not a valid version number identifying a protocol that can actually be spoken by relevant software. </p>
<p >Its specific meaning is identified specifically where it might be returned or taken by the API. </p>

</div>
</div>
<a id="a126eb85013fbeb11bcee34efbf0c79da" name="a126eb85013fbeb11bcee34efbf0c79da"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a126eb85013fbeb11bcee34efbf0c79da">&#9670;&nbsp;</a></span>S_VER_UNSUPPORTED</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">constexpr <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592">proto_ver_t</a> ipc::transport::Protocol_negotiator::S_VER_UNSUPPORTED = 0</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span><span class="mlabel">constexpr</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>A <a class="el" href="classipc_1_1transport_1_1Protocol__negotiator.html#a35fb3885d39f11d0c1f7860e64194592" title="Type sufficient to store a protocol version; positive values identify newer versions of a protocol; w...">proto_ver_t</a> value, namely zero, which is a reserved value indicating "unsupported version"; it is not a valid version number identifying a protocol that can actually be spoken by relevant software. </p>
<p >Its specific meaning is identified specifically where it might be returned or taken by the API. </p>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>transport/<a class="el" href="protocol__negotiator_8hpp.html">protocol_negotiator.hpp</a></li>
<li>transport/<a class="el" href="protocol__negotiator_8cpp.html">protocol_negotiator.cpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu May 2 2024 23:56:35 for Flow-IPC by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
